package db

import (
	"scase.io/application-auto-scaling-service/pkg/common"
	"time"

	"github.com/beego/beego/v2/client/orm"
	"github.com/pkg/errors"
)

const (
	tableNameEvent = "event"
)

type Event struct {
	Id           string    `orm:"column(id);size(64);pk"`
	Name         string    `orm:"column(name);size(64)"`
	ResourceType string    `orm:"column(resource_type);size(64)"`
	TraceService string    `orm:"column(trace_service);size(64)"`
	ResourceId   string    `orm:"column(resource_id);size(64)"`
	ResourceName string    `orm:"column(resource_name);size(64)"`
	TraceState   string    `orm:"column(trace_state);size(64)"`
	EventType    string    `orm:"column(event_type);size(64)"`
	ProjectId    string    `orm:"column(project_id);size(64)"`
	SourceIp     string    `orm:"column(source_ip);size(64)"`
	RecordTime   time.Time `orm:"column(record_time);type(datetime);auto_now_add"`
	Details      string    `orm:"column(details);type(text)"`
	SmnMessage   string    `orm:"column(message);size(1024)"`
	NoticeState  string    `orm:"column(notice_state);type(text)"`
}

// 返回索引
func (a *Event) TableIndex() [][]string {
	return [][]string{
		{"ProjectId"},
		{"ResourceType"},
		{"TraceState"},
		{"RecordTime"},
		{"EventType"},
		{"Name"},
	}
}

type EventTableOpt struct {
}

func GetEventTableOpt() *EventTableOpt {
	return &EventTableOpt{}
}

func (e *EventTableOpt) Insert(event *Event) error {
	_, err := ormer.Insert(event)
	if err != nil {
		return errors.Wrapf(err, "insert event err, event Id[%s]", event.Id)
	}
	return nil
}

func (e *EventTableOpt) Update(event *Event) error {
	_, err := ormer.Update(event)
	if err != nil {
		return errors.Wrapf(err, "update event err, event Id[%s]", event.Id)
	}
	return nil
}

func (e *EventTableOpt) Delete(id string) error {
	var event Event
	err := ormer.QueryTable(tableNameEvent).Filter(fieldNameId, id).One(&event)
	if err != nil {
		return errors.Wrapf(err, "query event err, event id [%s]", id)
	}
	_, err = ormer.Delete(&event)
	if err != nil {
		return errors.Wrapf(err, "delete event err, event id [%s]", id)
	}
	return nil
}

func (e *EventTableOpt) List(cond *orm.Condition, offset int, limit int) (*[]Event, error) {
	var events = &[]Event{}
	_, err := ormer.QueryTable(tableNameEvent).SetCond(cond).OrderBy("-record_time", "-name").Offset(offset * limit).Limit(limit).All(events)
	if err != nil {
		return nil, errors.Wrap(err, "list event err")
	}
	return events, nil
}

func (e *EventTableOpt) Count(cond *orm.Condition) (int, error) {
	var events = &[]Event{}
	count, err := ormer.QueryTable(tableNameEvent).SetCond(cond).Limit(common.DefaultListEventLimit).All(events)
	if err != nil {
		return 0, errors.Wrap(err, "list event err")
	}
	return int(count), nil
}

func (e *EventTableOpt) Show(id string) (*Event, error) {
	var event Event
	err := ormer.QueryTable(tableNameEvent).Filter(fieldNameId, id).One(&event)
	if err != nil {
		return nil, errors.Wrapf(err, "show event err, event id [%s]", id)
	}
	return &event, nil
}

func (e *EventTableOpt) CheckExist(cond *orm.Condition) bool {
	return ormer.QueryTable(tableNameEvent).SetCond(cond).Exist()
}
